/* Copyright (c) 2004-2024 Peigen.info. All rights reserved. */
package info.peigen.hotpot.component.open.api.facade.processor.base;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.StopWatch;
import cn.hutool.core.lang.Assert;
import com.alibaba.fastjson2.annotation.JSONField;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import info.peigen.hotpot.common.core.result.ListResult;
import info.peigen.hotpot.common.core.result.PageResult;
import info.peigen.hotpot.common.core.result.ResultBase;
import info.peigen.hotpot.common.core.result.SingleResult;
import info.peigen.hotpot.component.data.repository.Entity;
import info.peigen.hotpot.component.open.api.facade.Api;
import info.peigen.hotpot.component.open.api.facade.order.OpenApiOrder;
import lombok.*;
import lombok.experimental.Accessors;
import lombok.experimental.FieldDefaults;

import java.io.Serial;
import java.io.Serializable;
import java.sql.Timestamp;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * <b>(OpenApiProcessorServiceContext)</b>
 * 所有服务的上下文
 *
 * @author Peigen
 * @version 1.0.0
 * @since 2019/05/18
 */
@SuppressWarnings({"rawtypes", "unchecked"})
@Builder
@Data
@NoArgsConstructor
@AllArgsConstructor
@FieldDefaults(level = AccessLevel.PRIVATE)
@Accessors(chain = true)
public class OpenApiProcessorServiceContext<ORDER extends OpenApiOrder, RESULT extends ResultBase> implements Serializable {
    @Serial
    private static final long serialVersionUID = -7996169895294878828L;

    /** 当前数据库时间戳 <code>currentTimestamp</code> */
    Timestamp currentTimestamp;

    /** 请求参数 <code>order</code> */
    ORDER order;

    /** 应答返回 <code>result</code> */
    RESULT result;

    /** 其他可能需要传输的领域对象 <code>domain</code> */
    Api api;

    /** PartnerInfo对象 */
    Object partnerInfo;

    /** 处理器集合 */
    @Builder.Default
    List<OpenApiProcessor> processors = Lists.newArrayList();

    /** 临时用于传递entity */
    Entity entity;

    /** 异常显示传递，用来特殊化处理 */
    Exception exception;

    /** token */
    String token;

    /** 扩展参数 */
    @Builder.Default
    Map<String, Object> extend = Maps.newHashMap();

    @Builder.Default
    @JSONField(serialize = false, deserialize = false)
    StopWatch watch = new StopWatch();

    public OpenApiProcessorServiceContext(ORDER order, RESULT result) {
        this.order = order;
        this.result = result;
    }

    public void addProcessors(OpenApiProcessor... addProcessors) {
        Assert.isTrue(CollUtil.isNotEmpty(Arrays.stream(addProcessors).iterator()), "不可增加空处理器!");

        // 增加处理器
        processors.addAll(Arrays.asList(addProcessors));
    }

    /**
     * Result包装
     *
     * @param result ResultBase
     */
    public void resultWrap(ResultBase result) {
        this.result.setResult(result);
        if (result instanceof SingleResult<?> single) {
            SingleResult singleResult = (SingleResult) this.result;
            singleResult.setInfo(single.getInfo());
        } else if (result instanceof ListResult<?> list) {
            ListResult listResult = (ListResult) this.result;
            listResult.setInfo(list.getInfo());
        } else if (result instanceof PageResult<?> page) {
            PageResult pageResult = (PageResult) this.result;
            pageResult.setInfo(page.getInfo());
        }
    }
}